package com.duoketech.service;

import com.duoketech.exception.ValidateException;
import com.duoketech.model.AbstractModel;
import com.duoketech.utils.search.EqualCondition;
import com.duoketech.utils.search.QueryConstructor;
import com.jfinal.kit.Kv;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Page;

import java.util.Date;
import java.util.Map;

public abstract class AbstractService {


    private String querySQLCommand="";

    public String getOrderClause() {
        return orderClause;
    }

    public void setOrderClause(String orderClause) {
        this.orderClause = orderClause;
    }

    private String orderClause="";


    public void setQuerySQLCommand(String querySQLCommand) {
        this.querySQLCommand = querySQLCommand;
    }


    public abstract void validatorAdd(Model<?> model,Kv kv) throws ValidateException, com.duoketech.exception.ValidateException;

    public abstract void validatorUpdate(Model<?> model,Kv kv) throws ValidateException, com.duoketech.exception.ValidateException;


    public abstract void beforAdd(Model<?> model,Kv kv) throws ValidateException;
    public abstract void afterAdd(Model<?> model,Kv kv) throws ValidateException;


    public abstract void beforUpdate(Model<?> model,Kv kv) throws ValidateException;
    public abstract void afterUpdate(Model<?> model,Kv kv) throws ValidateException;


    public abstract void beforQuery(int id,Model<?> model,Kv kv) throws ValidateException;
    public abstract void afterQuery(int id,Model<?> model,Kv kv) throws ValidateException;


    public abstract void beforDelete(int id,Model<?> model,Kv kv) throws ValidateException;
    public abstract void afterDelete(int id,Model<?> model,Kv kv) throws ValidateException;

    public Page<?> pageAllRecord(Model<?> model, int pageNum, int pageSize, Kv kv){

        QueryConstructor queryConstruct = new QueryConstructor();
        setQuerySQLCommand("select * ");
        setOrderClause(" order by id desc ");
        queryConstruct.setCommand("from "+tableName());
        queryConstruct.setOrderSql(orderClause);

        builderSQLExpected(model,queryConstruct,kv);
        String sql = queryConstruct.buildSQL();
        return model.paginate(pageNum, pageSize,querySQLCommand, sql,queryConstruct.getParams().toArray());
    }

    public int  doAdd(Model<?> model,Kv kv) throws ValidateException {
        validatorAdd(model,kv);
        beforAdd(model,kv);
        model.set(AbstractModel.STATUS,AbstractModel.STATUS_NORMAL);
        model.set(AbstractModel.CREATE_TIME,new Date());
        model.save();
        afterAdd(model,kv);
        return model.getInt(AbstractModel.ID);
    }

    public void  update(Model<?> model,Kv kv) throws ValidateException {
        validatorUpdate(model,kv);
        beforUpdate(model,kv);
        model.set(AbstractModel.MODIFY_TIME,new Date());
        model.update();
        afterUpdate(model,kv);
    }

    public Model<?> queryBy(int id,Model<?> model,Kv kv) throws ValidateException {
        beforQuery(id,model,kv);
        Model<?> result= model.findById(id);
        afterQuery(id,model,kv);
        return result ;
    }

    public void  deleteBy(int id,Model<?> model,Kv kv) throws ValidateException {
        beforDelete(id,model,kv);
        model.set(AbstractModel.ID,id);
        model.set(AbstractModel.STATUS,AbstractModel.STATUS_DEL);
        model.set(AbstractModel.MODIFY_TIME,new Date());
        model.update();
        afterDelete(id,model,kv);
    }

    public abstract String tableName();

    /*
        根据查询条件创建对应的SQL语句
     */
    public abstract void builderSQLExpected(Model<?> model,QueryConstructor queryConstruct,Kv kv);

}
